package gti310.tp4;

import java.util.ArrayList;

/**
 * La classe Quantification contient les tables servant à quantifier les valeurs
 * des blocs 8x8 reçu en paramètre dans le constructeur. La méthode 
 * executerQuantification effectue le parcours des blocs et applique la 
 * quantification.
 * 
 * @author Émile Robinson et Fredy Alexander Bonilla
 * @date 2014-12-04
 *
 */
public class quantification{
	
	//Contante de la taille des bloc
	private static final int N = 8;

	//La tables de quantification
	public int quantifY[][] = {
			{16,40,40,40,40,40,51,61},	
			{40,40,40,40,40,58,60,55},
			{40,40,40,40,40,57,69,56},
			{40,40,40,40,51,87,80,62},
			{40,40,40,56,68,109,103,77},
			{40,40,55,64,81,104,113,92},
			{49,64,78,87,103,121,120,101},
			{72,92,95,98,112,100,103,95}};
	public int quantifCbCr[][]= {
			{17,40,40,95,95,95,95,95},	
			{40,40,40,95,95,95,95,95},
			{40,40,40,95,95,95,95,95},
			{40,40,95,95,95,95,95,95},
			{95,95,95,95,95,95,95,95},
			{95,95,95,95,95,95,95,95},
			{95,95,95,95,95,95,95,95},
			{95,95,95,95,95,95,95,95}};
	public int facteurQ;
	private ListeComposant liste;

	/**
	 * Constructeur de la classe quantification, initialise la table de 
	 * quantification
	 * 
	 * @param facteurQ
	 */
	public quantification(int facteurQ, ListeComposant liste){
		this.facteurQ = facteurQ;		
		this.liste = liste;
	}
	
	/**
	 */
	public void executerQuantification(){
		
		//Valeur temporaire d'échange
		double [][] temp = new double [8][8];

		//Application de la quantif sur tous les bloc de 8x8 de chacune des composantes YCbCr
		for(int i=0; i<liste.getTaille(); i++){
			for(int j=0; j<liste.getComponent(i).size(); j++){

				if(i==0){
					//Application de la quantif sur chacun des bloc 8x8 du component actuel
					temp = liste.setIntToDouble(quantifier(liste.getComponent(i).get(j), 0));
					liste.getComponent(i).set(j, temp);
				}
				else{
					temp = liste.setIntToDouble(quantifier(liste.getComponent(i).get(j), 1));
					liste.getComponent(i).set(j, temp);
				}
			}//Fin du parcours des 1024 bloc de 8x8

		}//Fin du parcours des trois components
	}

	/**
	 * 
	 * @param inputData
	 * @return la matrice de valeur quantifiée 
	 */
	public int[][] quantifier(double inputData[][], int comp){

		int outputData[][] = new int[8][8];
		int i = 0;
		int j = 0;        

		double result;
		double alpha = 0;

		if(facteurQ >=1 && facteurQ <= 50){
			alpha = 50/facteurQ;
		}
		if(facteurQ >50 && facteurQ <= 99){
			alpha = (200-2*facteurQ)/100;
		}

		if(comp == 0){
			for (i=0; i<8; i++){
				for (j=0; j<8; j++){

					result = inputData[i][j] / (alpha*(quantifY[i][j]));
					outputData[i][j] = (int)(Math.round(result));
				}
			}
		}
		else if(comp == 1){
			for (i=0; i<8; i++){
				for (j=0; j<8; j++){

					result = inputData[i][j] / (alpha*(quantifCbCr[i][j]));
					outputData[i][j] = (int)(Math.round(result));
				}
			}
		}
		else{
			System.out.println("Erreur quantification");
			outputData = null;
		}

		return outputData;
	}




}